/*
 * SoftwareSAR - 1.0
 */
package br.com.cpqd.ssar.utilitarias;

/**
 * Classe Abstrata que Armazena os Atributos Geométricos Comuns aos Objetos
 * @author Rafael Buck
 * @version 1.1
 */
public abstract class AtributosGeometria {

    /**
     * Ponto do Referencial no Espaço 3D do Objeto
     */
    protected float[] referencial;
    /**
     * Identifica a Geometria
     * 0 : STL
     * 1 : Hexaedro
     * 2 : Cilindro
     * 3 : Esfera
     * 4 : Cone
     */
    protected int identificador;
    private float[] normal = new float[3];

    /**
     * Método Construtor
     * @param referencia float[]
     * @param identificador int
     */
    public AtributosGeometria(float[] referencia, int identificador) {
        this.referencial = referencia;
        this.identificador = identificador;
    }

    /**
     * Redimensiona o Objeto com Base em suas Propriedades Geométricas
     */
    public abstract void redimensionar();

    /**
     * Get the value of identificador
     * @return the value of identificador
     */
    public int getIdentificador() {
        return identificador;
    }

    /**
     * Set the value of identificador
     * @param identificador new value of identificador
     */
    public void setIdentificador(int identificador) {
        this.identificador = identificador;
    }

    /**
     * Retorna o vetor Normal
     * @return
     */
    public float[] getNormal() {
        return normal;
    }

    /**
     * Get the value of referencial
     * @return the value of referencial
     */
    public float[] getReferencial() {
        return referencial;
    }

    /**
     * Set the value of referencial
     * @param referencial new value of referencial
     */
    public void setReferencial(float[] referencial) {
        this.referencial = referencial;
    }

    /**
     * Get the value of referencial at specified index
     * @param index
     * @return the value of referencial at specified index
     */
    public float getReferencial(int index) {
        return this.referencial[index];
    }

    /**
     * Set the value of referencial at specified index.
     * @param index
     * @param newReferencial new value of referencial at specified index
     */
    public void setReferencial(int index, float newReferencial) {
        this.referencial[index] = newReferencial;
    }

    /**
     * Calcula o vetor normal
     * @param p1
     * @param p2
     * @param p3
     * @return
     */
    public float[] calcVetorNormal(Vertice p1, Vertice p2, Vertice p3) {

        Vertice vTemp1 = new Vertice();
        Vertice vTemp2 = new Vertice();


        double len = 0.0;

        /* Encontra vetor v1 */

        vTemp1.setCoordenada(0, p2.getCoordenada(0) - p1.getCoordenada(0));
        vTemp1.setCoordenada(1, p2.getCoordenada(1) - p1.getCoordenada(1));
        vTemp1.setCoordenada(2, p2.getCoordenada(2) - p1.getCoordenada(2));


        /* Encontra vetor v2 */
        vTemp2.setCoordenada(0, p3.getCoordenada(0) - p1.getCoordenada(0));
        vTemp2.setCoordenada(1, p3.getCoordenada(1) - p1.getCoordenada(1));
        vTemp2.setCoordenada(2, p3.getCoordenada(2) - p1.getCoordenada(2));


        /* Calculo do produto vetorial de v1 e v2 */
        normal[0] = ((p1.getCoordenada(1) * p2.getCoordenada(2)) - (p1.getCoordenada(2) * p2.getCoordenada(1)));
        normal[1] = ((p1.getCoordenada(2) * p2.getCoordenada(0)) - (p1.getCoordenada(0) * p2.getCoordenada(2)));
        normal[2] = ((p1.getCoordenada(0) * p2.getCoordenada(1)) - (p1.getCoordenada(1) * p2.getCoordenada(0)));


        /* normalizacao de n */

        len = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
        normal[0] /= len;
        normal[1] /= len;
        normal[2] /= len;

        return normal;
    }

    public abstract void addX();

    public abstract void addY();

    public abstract void addZ();
    
    public abstract void addX(float valor);

    public abstract void addY(float valor);

    public abstract void addZ(float valor);

    public abstract void subX();

    public abstract void subY();

    public abstract void subZ();
    
    public abstract void subX(float valor);

    public abstract void subY(float valor);

    public abstract void subZ(float valor);

    public abstract void setRaio(float radius);

    public abstract float getRaio();

    public abstract float getAltura();

    public abstract void setAltura(float height);

    public abstract float[] getFirsPoint();

    public abstract float[] getSecondPoint();

    public abstract void setSecondPoint(float[] secondPoint);

    public abstract void setFirsPoint(float[] firstPoint);
    // --- STL ---
    public abstract String getCaminhoArquivo();

    public abstract void setCaminhoArquivo(String caminhoArquivo);

    public abstract void redimensionarSTL(float[] min, float[] max);

    public abstract void setNElements(int n);

    public abstract int getNElements();

    public abstract Triangulo[] getListaTriangulosSTL();

    public abstract Triangulo[] triangularizarGeometria();
    // --- Métodos Utilizados pelo Domínio Computacional ---
    public abstract int getNSteps();

    public abstract int getDiscretizacaoX();

    public abstract void setDiscretizacaoX(int discretizacaoX);

    public abstract int getDiscretizacaoY();

    public abstract void setDiscretizacaoY(int discretizacaoY);

    public abstract int getDiscretizacaoZ();

    public abstract void setDiscretizacaoZ(int discretizacaoZ);

    public abstract double getDx();

    public abstract double getDy();

    public abstract double getDz();

    public abstract int getPmlXi();

    public abstract void setPmlXi(int pmlXi);

    public abstract int getPmlXf();

    public abstract void setPmlXf(int pmlXf);

    public abstract int getPmlYi();

    public abstract void setPmlYi(int pmlYi);

    public abstract int getPmlYf();

    public abstract void setPmlYf(int pmlYf);

    public abstract int getPmlZi();

    public abstract void setPmlZi(int pmlZi);

    public abstract int getPmlZf();

    public abstract void setPmlZf(int pmlZf);

    public abstract double getEscala();

    public abstract void setEscala(double escala);

    public abstract void setEscala(String tipo);


}
